//
//  KeychainOrderItem.m
//  PaymentDemo
//
//  Created by ycgame on 2020/4/21.
//  Copyright © 2020 maqianzheng. All rights reserved.
//

#import "OPKKeychainItem.h"

@interface OPKKeychainItem()
@property(nonatomic, copy)NSString *service;
@property(nonatomic, copy)NSString *account;
@property(nonatomic, copy)NSString *accessGroup;

@end

@implementation OPKKeychainItem

/// 初始化
- (instancetype)initWithService:(NSString *)service Account:(NSString *)account
{
    self = [super init];
    if (self) {
        self.service = service;
        self.account = account;
        self.accessGroup = nil;
    }
    return self;
}

/// 查
- (id)readItem {
    if (kSecClassGenericPassword == nil || kSecMatchLimitOne == nil) { return nil; }
    NSDictionary *matchSecItems = @{ (id)kSecClass: (id)kSecClassGenericPassword,
                                    (id)kSecAttrService: _service,
                                    (id)kSecAttrAccount: _account,
                                    (id)kSecMatchLimit: (id)kSecMatchLimitOne,
                                    (id)kSecReturnData: @(YES) };
    CFTypeRef dataRef = nil;
    OSStatus errorCode = SecItemCopyMatching((CFDictionaryRef)matchSecItems, (CFTypeRef *)&dataRef);
    if (errorCode != 0) {   /// 有错误
        NSLog(@"OPKKeychainItem read Error Code: %d", (int)errorCode);
    }
    if (dataRef != nil) {
        @try {
            id item = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)dataRef];
            return item;
        } @catch (NSException *exception) {
            NSLog(@"OPKKeychainItem Read: %@", exception.reason);
        }
    }
    return nil;
}

/// 保存
- (void)save:(id<NSCoding>)item {
    if (kSecClassGenericPassword == nil) { return; }
    @try {
        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:item];
        if (data == nil) {
            NSLog(@"OPKKeychainItem Archived Object nil");
            return;
        }
        /// 如果查到对应对象，则更新
        if ([self readItem] == nil) {
            NSDictionary *saveSecItems = @{ (id)kSecClass: (id)kSecClassGenericPassword,
                                            (id)kSecAttrService: _service,
                                            (id)kSecAttrAccount: _account,
                                            (id)kSecValueData: data };
            OSStatus saveStatus = SecItemAdd((CFDictionaryRef)saveSecItems, NULL);
            if (saveStatus != 0) {
                NSLog(@"OPKKeychainItem Add Status: %d", (int)saveStatus);
            }
        } else {    /// 查不到，则新增
            NSDictionary *queryItems = @{ (id)kSecClass: (id)kSecClassGenericPassword,
                                          (id)kSecAttrService: _service,
                                          (id)kSecAttrAccount: _account };
            NSDictionary *updateItems = @{ (id)kSecValueData: data };
            OSStatus updateStatus = SecItemUpdate((CFDictionaryRef)queryItems, (CFDictionaryRef)updateItems);
            if (updateStatus != 0) {
                NSLog(@"OPKKeychainItem Update Status: %d", (int)updateStatus);
            }
        }
    } @catch (NSException *exception) {
        NSLog(@"OPKKeychainItem Save Status: %@", exception.reason);
    }

}

/// 删除
- (void)delete {
    if (kSecClassGenericPassword == nil) { return; }
    NSDictionary *deleteSecItems = @{ (id)kSecClass: (id)kSecClassGenericPassword,
                                      (id)kSecAttrService: _service,
                                      (id)kSecAttrAccount: _account };
    OSStatus errorCode = SecItemDelete((CFDictionaryRef)deleteSecItems);
    if (errorCode != 0) {    
        NSLog(@"OPKKeychainItem Delete Error Code: %d", (int)errorCode);
    }
}

@end

@implementation OPKKeychainItem (OPKOrder)

+ (NSString *)orderService {
    NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
    if (bundleId != nil) {
        return [bundleId stringByAppendingFormat:@".order.v4"];
    }
    return @"com.yunchang.game.open.order.v4";
}

+ (void)setOrderItem:(OPKOrderItem *)item forKey:(NSString *)key {
    if (item == nil || key == nil) { return; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self orderService] Account:key];
    [query save:item];
}

+ (void)removeOrderItemForKey:(NSString *)key {
    if (key == nil) { return; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self orderService] Account:key];
    [query delete];
}

+ (OPKOrderItem *)orderItemForKey:(NSString *)key {
    if (key == nil) { return nil; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self orderService] Account:key];
    return [query readItem];
}

@end

@implementation OPKKeychainItem (OPKTransaction)

+ (NSString *)transactionService {
    NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
    if (bundleId != nil) {
        return [bundleId stringByAppendingFormat:@".transaction.v6"];
    }
    return @"com.yunchang.game.open.transaction.v6";
}

+ (void)setTransactionItem:(OPKTransactionItem *)item forKey:(NSString *)key {
    if (item == nil || key == nil) { return; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self transactionService] Account:key];
    [query save:item];
}

+ (void)removeTransactionItemForKey:(NSString *)key {
    if (key == nil) { return; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self transactionService] Account:key];
    [query delete];
}

+ (OPKTransactionItem *)transactionItemForKey:(NSString *)key {
    if (key == nil) { return nil; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self transactionService] Account:key];
    return [query readItem];
}

@end

@implementation OPKKeychainItem (OPKUserId)

static NSString * const uidKey = @"com.yunchang.game.open.uid.v6";

+ (NSString *)uidService {
    NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
    if (bundleId != nil) {
        return [bundleId stringByAppendingFormat:@".uid.v6"];
    }
    return @"com.yunchang.game.open.uid.v6";
}

+ (void)setUid:(NSString *)uid {
    if (uid == nil) { return; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self uidService] Account:uidKey];
    [query save:uid];
}
+ (void)removeUid {
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self uidService] Account:uidKey];
    [query delete];
}
+ (NSString *)uid {
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self uidService] Account:uidKey];
    return [query readItem];
}

@end

@implementation OPKKeychainItem (OPKValue)

+ (NSString *)valueService {
    NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
    if (bundleId != nil) {
        return [bundleId stringByAppendingFormat:@".value.v6"];
    }
    return @"com.yunchang.game.open.value.v6";
}

+ (void)setValue:(NSString *)value forKey:(NSString *)key {
    if (value == nil || key == nil) { return; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self valueService] Account:key];
    [query save:value];
}
+ (void)removeValueForKey:(NSString *)key {
    if (key == nil) { return; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self valueService] Account:key];
    [query delete];
}
+ (NSString *)valueForKey:(NSString *)key {
    if (key == nil) { return nil; }
    OPKKeychainItem *query = [[OPKKeychainItem alloc] initWithService:[self valueService] Account:key];
    return [query readItem];
}

@end

